package cn.calm.bundle.action;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.apache.struts2.json.annotations.JSON;
import org.apache.struts2.osgi.interceptor.ServiceAware;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;

import cn.calm.bundle.Activator;
import cn.calm.bundle.entity.Bundle;
import cn.calm.bundle.service.IBundleService;
import cn.calm.bundle.util.BundleUtil;
import cn.calm.commons.action.CurdAction;
import cn.calm.commons.entity.PageMode;
import cn.calm.commons.util.FileUtils;

@SuppressWarnings("rawtypes")
public class BundleAction<E extends Bundle, S extends IBundleService<E>>
		extends CurdAction<E, S> implements ServiceAware<IBundleService> {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private File file;
	private String fileFileName;
	private InputStream inputStream;
	@SuppressWarnings("unchecked")
	public String upload() {
		String uploadDir = getServletContext().getRealPath("/temp/");
		File destFile = null;
		if (fileFileName != null) {
			String pathname = uploadDir + File.separator + fileFileName;
			destFile = new File(pathname);
			if (destFile.exists()) {
				addActionError("EMFM0001", null, fileFileName);
			} else {
				try {
					FileUtils.copyFile(file, destFile);
				} catch (IOException e) {
					addActionError(e.getMessage());
				}

			}
		}
		if (destFile != null && !hasErrors()) {
			try {
				t = (E) BundleUtil.readBundleInfo(destFile);
			} catch (Exception e) {
				addActionError("EMBM0001", null, destFile.getName());
			}
		}
		if (hasErrors()) {
			destFile.delete();
			return INPUT;
		}
		return "upload";
	}

	@Override
	public String add() {
		File file = null;
		try{
			String uploadDir = getServletContext().getRealPath("/temp/");
			file = new File(uploadDir + File.separator + t.getBundleFileName());
			if (!file.isFile()) {
				addActionMessage("EMFM0001", null, t.getBundleFileName());
				return INPUT;
			}
			FileInputStream fis = null;
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			byte buff[] = new byte[1024 * 10];
			int length;
			try {
				fis = new FileInputStream(file);
				while ((length = fis.read(buff)) != -1) {
					baos.write(buff, 0, length);
				}
				t.setContent(baos.toByteArray());
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if (baos != null) {
					try {
						baos.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				if (fis != null) {
					try {
						fis.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
			return super.add();
		}finally{
			if(file!=null){
				file.delete();
			}
		}
	}

	public String install() {
		String uploadDir = getServletContext().getRealPath("/bundlesTemp/");
	
		t = service.load(t);
		File file=new File(uploadDir);
		if(!file.isDirectory()){
			file.mkdirs();
		}
		FileUtils.byteToFile(t.getContent(), uploadDir+"/"+t.getBundleFileName());
		try {
			
			org.osgi.framework.Bundle b=getBundleContext()
					.installBundle("file:/"+uploadDir+"/"+t.getBundleFileName());
			if(b!=null)
			{
				b.start();
			}
		} catch (BundleException e) {
			e.printStackTrace();
		} finally {
			
		}
		return "install";
	}

	public String download() {
		t = service.load(t);
		ByteArrayInputStream bais = null;
		try {
			bais = new ByteArrayInputStream(t.getContent());
			setInputStream(bais);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			if (bais != null) {
				try {
					bais.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return "download";
	}

	@Override
	public String getModeName() {
		return "bundle";
	}

	@Override
	public Collection<String> getActionErrors() {
		return super.getActionErrors();
	}

	@Override
	public Map<String, List<String>> getFieldErrors() {
		return super.getFieldErrors();
	}

	@JSON(serialize = false)
	public BundleContext getBundleContext() {
		return Activator.context;
	}

	@Override
	public E getT() {
		return super.getT();
	}

	@Override
	public PageMode getPageMode() {
		return super.getPageMode();
	}

	public void setFile(File file) {
		this.file = file;
	}

	public void setFileFileName(String fileFileName) {
		this.fileFileName = fileFileName;
	}

	public String getFileFileName() {
		return fileFileName;
	}

	@SuppressWarnings("unchecked")
	@Override
	public void setServices(List<IBundleService> services) {
		if (service == null) {
			if (services != null && services.size() > 0) {
				service = (S) services.get(0);
			}
		}
	}

	public InputStream getInputStream() {
		return inputStream;
	}

	public void setInputStream(InputStream inputStream) {
		this.inputStream = inputStream;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Class<E> getEntityClass() {
		return (Class<E>) Bundle.class;
	}

}
